package br.com.werp.regras.acesso.controle;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import br.com.werp.regras.acesso.integracao.FabricaDAO;
import br.com.werp.regras.acesso.integracao.RoleUrlDAO;
import br.com.werp.regras.acesso.integracao.UsuarioRoleDAO;
import br.com.werp.regras.geral.Algoritimo;
import br.com.werp.regras.geral.Auditoria;
import br.com.werp.regras.geral.FabricaSubSistema;
import br.com.werp.regras.geral.util.BeanUtil;
import br.com.werp.regras.geral.util.Constantes;
import br.com.werp.regras.geral.util.Util;
import br.com.werp.regras.geral.vos.acesso.RoleUrlFormVO;
import br.com.werp.regras.geral.vos.acesso.RoleUrlVO;
import br.com.werp.regras.geral.vos.suporte.UsuarioRoleVO;
import br.com.werp.regras.geral.vos.tabelas.Role;
import br.com.werp.regras.geral.vos.tabelas.Role_url;
import br.com.werp.regras.geral.vos.tabelas.Usuario;
import br.com.werp.regras.geral.vos.tabelas.Usuario_role;


/**
 * @author Sobreira
 * Created on 08/09/2004
 */
public class ControleRole {
    /**
     * AUDITADO
     */
    public void inserirRoles(String requisitor, String usuario, String[] roles)
        throws Exception {
        UsuarioRoleDAO usuarioRoleDAO = FabricaDAO.getUsuarioRoleDAO();
        List listaUsuarioRole = usuarioRoleDAO.obterRoles(usuario);
        Auditoria auditoria = FabricaSubSistema.getAuditoria();
        Object object = usuarioRoleDAO.iniciarTransacao();

        try {
            for (Iterator iter = listaUsuarioRole.iterator(); iter.hasNext();) {
                Role roleVO = (Role) iter.next();
                usuarioRoleDAO.removerRole(usuario, roleVO.getRole_usuario(),
                    object);
                auditoria.auditarRecurso(object, requisitor,
                    new Role(usuario, roleVO.getRole_usuario()),
                    Auditoria.EXCLUIR);
            }

            for (int i = 0; i < roles.length; i++) {
                usuarioRoleDAO.inserirRole(usuario, roles[i], object);
                auditoria.auditarRecurso(object, requisitor,
                    new Role(usuario, roles[i]), Auditoria.ALTERAR);
            }

            usuarioRoleDAO.concluirTransacao(object);
        } catch (Exception e) {
            usuarioRoleDAO.abortarTransacao(object);
            throw e;
        }
    }

    /**
     * AUDITADO
     */
    public void removerRoles(String requisitor, String usuario, String[] roles)
        throws Exception {
        UsuarioRoleDAO usuarioRoleDAO = FabricaDAO.getUsuarioRoleDAO();
        Auditoria auditoria = FabricaSubSistema.getAuditoria();
        Object object = usuarioRoleDAO.iniciarTransacao();

        try {
            for (int i = 0; i < roles.length; i++) {
                usuarioRoleDAO.removerRole(usuario, roles[i], object);
                auditoria.auditarRecurso(object, requisitor,
                    new Role(usuario, roles[i]), Auditoria.EXCLUIR);
            }

            usuarioRoleDAO.concluirTransacao(object);
        } catch (Exception e) {
            usuarioRoleDAO.abortarTransacao(object);
            throw e;
        }
    }

    public List obterRoles(String usuario) throws Exception {
        UsuarioRoleDAO usuarioRoleDAO = FabricaDAO.getUsuarioRoleDAO();

        return usuarioRoleDAO.obterRoles(usuario);
    }

    public List obterRolesDisponiveis(String usuario) throws Exception {
        UsuarioRoleDAO usuarioRoleDAO = FabricaDAO.getUsuarioRoleDAO();
        List userRoles = usuarioRoleDAO.obterRoles(usuario);
        List returnList = new ArrayList();
        List list = usuarioRoleDAO.obterRoles();

        if (userRoles.isEmpty()) {
            return list;
        }

        for (Iterator iter = list.iterator(); iter.hasNext();) {
            Role roleVO = (Role) iter.next();

            if (!userRoles.contains(roleVO)) {
                returnList.add(roleVO);
            }
        }

        return returnList;
    }

    public void atualizarRoles(Object key, String requisitor, String usuario,
        List roles) throws Exception {
        UsuarioRoleDAO usuarioRoleDAO = FabricaDAO.getUsuarioRoleDAO();
        Auditoria auditoria = FabricaSubSistema.getAuditoria();
        List verificaRoles = usuarioRoleDAO.obterUsuarioRole(key,usuario);
        
        apagarRoles(key, requisitor, roles, usuario);

        for (Iterator iter = roles.iterator(); iter.hasNext();) {
            UsuarioRoleVO role = (UsuarioRoleVO) iter.next();
           if (!verificaRoles.contains(role)) {
			usuarioRoleDAO.inserirRole(usuario, role.getRole_usuario(), key);
            Usuario_role usuario_role = new Usuario_role();
            usuario_role.setRole_usuario(role.getRole_usuario());
            usuario_role.setUsur_login(usuario);
            auditoria.auditarRecurso(key, requisitor,
                    usuario_role, Auditoria.ALTERAR);
           }
            
        }
    }

    private void apagarRoles(Object key, String requisitor, List roles,
        String usuario) throws Exception {
        UsuarioRoleDAO usuarioRoleDAO = FabricaDAO.getUsuarioRoleDAO();
        Algoritimo algoritimo = FabricaSubSistema.getAlgoritimo();
        Auditoria auditoria = FabricaSubSistema.getAuditoria();

        List usuarioBanco = usuarioRoleDAO.obterUsuarioRole(key,usuario);

        List remover = algoritimo.gerarListaRemoverIdsReais(roles, usuarioBanco);

        for (Iterator iter = remover.iterator(); iter.hasNext();) {
            UsuarioRoleVO roleBanco = (UsuarioRoleVO) iter.next();

            usuarioRoleDAO.removerRole(usuario, roleBanco.getRole_usuario(), key);

            Role role = new Role();
            BeanUtil.copiarVO(roleBanco, role);
            auditoria.auditarRecurso(key, requisitor, role, Auditoria.EXCLUIR);
        }
    }

    public void removerTodasRoles(Object key, Usuario usuario, String requisitor)
        throws Exception {
        FabricaDAO.getUsuarioRoleDAO().removerTodasRoles(key, usuario);
    }

    public void carregarRoleUrl(Object form, List roleUrl)
        throws Exception {
        RoleUrlFormVO roleUrlFormVO = new RoleUrlFormVO();
        BeanUtil.copiarVO(form, roleUrlFormVO);
        roleUrl.clear();

        RoleUrlDAO roleUrlDAO = FabricaDAO.getRoleUrlDAO();
        RoleUrlVO roleUrlVO = new RoleUrlVO();
        roleUrlVO.setRour_role(roleUrlFormVO.getRole_usuario());
        roleUrl.addAll(roleUrlDAO.pesquisarRoleUrl(roleUrlVO));
    }

    public void manterListaRoleUrl(Object form, List roleUrls)
        throws Exception {
        RoleUrlFormVO roleUrlFormVO = new RoleUrlFormVO();
        BeanUtil.copiarVO(form, roleUrlFormVO);

        Algoritimo algoritimo = FabricaSubSistema.getAlgoritimo();

        if (Constantes.ADICIONAR.equals(roleUrlFormVO.getOp())) {
            RoleUrlVO roleUrlVO = new RoleUrlVO();
            Util.campoMandatorio(roleUrlFormVO.getUrl_path(), "Escolha uma url");
            BeanUtil.copiarVOStringTipo(roleUrlFormVO, roleUrlVO);

            roleUrlVO.setRour_role(roleUrlFormVO.getRole_usuario());
            roleUrlVO.setRour_url(roleUrlVO.getUrl_id());
            algoritimo.criarIdVirtual(roleUrls, roleUrlVO);
        } else {
            algoritimo.removerIdVirtual(roleUrls, roleUrlFormVO.getUrls());
        }
    }

    public void salvarRoleUrl(Object form, List roleUrls, String usuario)
        throws Exception {
        Auditoria auditoria = FabricaSubSistema.getAuditoria();
        RoleUrlDAO roleUrlDAO = FabricaDAO.getRoleUrlDAO();
        RoleUrlFormVO roleUrlFormVO = new RoleUrlFormVO();
        BeanUtil.copiarVO(form, roleUrlFormVO);

        Object key = roleUrlDAO.iniciarTransacao();

        try {
            apagarUrlsExcluidas(key, roleUrlFormVO.getRole_usuario(), roleUrls,
                usuario);

            for (Iterator iter = roleUrls.iterator(); iter.hasNext();) {
                RoleUrlVO roleUrlVO = (RoleUrlVO) iter.next();

                if (roleUrlVO.isIdVirtual()) {
                    Role_url role_url = new Role_url();
                    BeanUtil.copiarVO(roleUrlVO, role_url);
                    roleUrlDAO.inserirRoleUrle(key, role_url);
                    auditoria.auditarRecurso(key, usuario, role_url,
                        Auditoria.INCLUIR);
                }
            }

            roleUrlDAO.concluirTransacao(key);
        } catch (Exception e) {
            roleUrlDAO.abortarTransacao(key);
            throw e;
        }
    }

    private void apagarUrlsExcluidas(Object key, String role, List roleUrls,
        String usuario) throws Exception {
        Auditoria auditoria = FabricaSubSistema.getAuditoria();
        Algoritimo algoritimo = FabricaSubSistema.getAlgoritimo();
        RoleUrlVO roleUrlVO = new RoleUrlVO();
        roleUrlVO.setRour_role(role);

        RoleUrlDAO roleUrlDAO = FabricaDAO.getRoleUrlDAO();
        List roleUrlsBanco = roleUrlDAO.pesquisarRoleUrl(roleUrlVO);
        List remover = algoritimo.gerarListaRemoverIdsReais(roleUrls,
                roleUrlsBanco);

        for (Iterator iter = remover.iterator(); iter.hasNext();) {
            RoleUrlVO roleUrlVOApagar = (RoleUrlVO) iter.next();
            Role_url role_url = new Role_url();
            BeanUtil.copiarVO(roleUrlVOApagar, role_url);
            roleUrlDAO.apagarRole_url(key, role_url);
            auditoria.auditarRecurso(key, usuario, role_url, Auditoria.EXCLUIR);
        }
    }
}
